package com.huiminpay.merchant.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.common.cache.domain.PageVO;
import com.huiminpay.common.cache.util.PhoneUtil;
import com.huiminpay.merchant.api.MerchantService;
import com.huiminpay.merchant.convert.MerchantConvert;
import com.huiminpay.merchant.convert.StaffConvert;
import com.huiminpay.merchant.convert.StoreConvert;
import com.huiminpay.merchant.dto.MerchantDto;
import com.huiminpay.merchant.dto.StaffDTO;
import com.huiminpay.merchant.dto.StoreDTO;
import com.huiminpay.merchant.dto.StoreStaffDTO;
import com.huiminpay.merchant.entity.Merchant;
import com.huiminpay.merchant.entity.Staff;
import com.huiminpay.merchant.entity.Store;
import com.huiminpay.merchant.entity.StoreStaff;
import com.huiminpay.merchant.mapper.MerchantMapper;

import com.huiminpay.merchant.mapper.StaffMapper;
import com.huiminpay.merchant.mapper.StoreMapper;
import com.huiminpay.merchant.mapper.StoreStaffMapper;
import com.huiminpay.user.api.TenantService;
import com.huiminpay.user.api.dto.tenant.CreateTenantRequestDTO;
import com.huiminpay.user.api.dto.tenant.TenantDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author suozhenhua
 * @since 2021-03-15
 */
@Slf4j
@org.apache.dubbo.config.annotation.Service
public class MerchantServiceImpl implements MerchantService {
    @Autowired
    MerchantMapper merchantMapper;
    @Autowired
    StoreMapper storeMapper;
    @Autowired
    StaffMapper staffMapper;
    @Autowired
    StoreStaffMapper storeStaffMapper;
    @Reference
    private TenantService tenantService;

    @Override
    public MerchantDto queryMerchantById(Long merchantId) {
        Merchant merchant = merchantMapper.selectById(merchantId);
        MerchantDto merchantDTO = new MerchantDto();
        BeanUtils.copyProperties(merchant,merchantDTO);
        return merchantDTO;
    }
    @Override
    public MerchantDto creatMerchant1(MerchantDto merchantDto) throws BusinessException{
        if (merchantDto==null){
            throw new BusinessException(CommonErrorCode.E_100108); }
        //手机号为空
        if (StringUtils.isEmpty(merchantDto.getMobile())){
            throw new BusinessException(CommonErrorCode.E_100112); }
        if (!PhoneUtil.isMatches(merchantDto.getMobile())){
            throw new BusinessException(CommonErrorCode.E_100109); }
        if (StringUtils.isBlank(merchantDto.getUsername())){
            throw new BusinessException(CommonErrorCode.E_100110);
        }
        if (StringUtils.isBlank(merchantDto.getPassword())){
            throw new BusinessException(CommonErrorCode.E_100111);
        }
        LambdaQueryWrapper<Merchant> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Merchant::getMobile,merchantDto.getMobile());
        Integer num = merchantMapper.selectCount(wrapper);
        if (num>0){
            throw new BusinessException(CommonErrorCode.E_100113);
        }
        Merchant merchant = new Merchant();
        BeanUtils.copyProperties(merchantDto,merchant);
        merchant.setAuditStatus("0");
        merchantMapper.insert(merchant);
        merchantDto.setId(merchant.getId());
        return merchantDto;
    }

    @Override
    @Transactional
    public void applyMerchant(Long merchantId, MerchantDto merchantDto) throws BusinessException {
        if (merchantId==null||merchantDto==null){
            throw new BusinessException(CommonErrorCode.E_300009);
        }
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant==null){
            throw new BusinessException(CommonErrorCode.E_200002);
        }
        Merchant entity = MerchantConvert.INSTANCE.dto2entity(merchantDto);
        entity.setId(merchant.getId());
        entity.setMobile(merchant.getMobile());
        entity.setAuditStatus("1");
        entity.setTenantId(merchant.getTenantId());
        merchantMapper.updateById(entity);


    }

    @Override
    public StoreDTO crestStore(StoreDTO storeDTO) throws BusinessException {
        System.out.println(storeDTO);
        Store store = StoreConvert.INSTANCE.dto2entity(storeDTO);
        storeMapper.insert(store);
        StoreDTO storeDto = StoreConvert.INSTANCE.entity2dto(store);
        return storeDto;
    }

    @Override
    public StaffDTO creatStaff(StaffDTO staffDTO) throws BusinessException {
        if (StringUtils.isEmpty(staffDTO.getMobile())){
            throw new BusinessException(CommonErrorCode.E_100112);
        }
        if (!PhoneUtil.isMatches(staffDTO.getMobile())){
            throw new BusinessException(CommonErrorCode.E_100109);
        }
        if (staffDTO.getUsername()==null){
            throw new BusinessException(CommonErrorCode.E_100110);
        }
        if (isExistStaffByUsername(staffDTO.getUsername(),staffDTO.getMerchantId())){
            throw new BusinessException(CommonErrorCode.E_100114);
        }
        Staff staff = StaffConvert.INSTANCE.dto2entity(staffDTO);
        staffMapper.insert(staff);
        StaffDTO staffDto = StaffConvert.INSTANCE.entity2dto(staff);
        return staffDto;
    }
    private boolean isExistStaffByUsername(String userName, Long merchantId){

        Integer num = staffMapper.selectCount(new LambdaQueryWrapper<Staff>().eq(Staff::getUsername,userName).
                eq(Staff::getMerchantId,merchantId));
        return num>0;


    }
    @Override
    public void bindStaffToStore(Long storeId, Long staffId) {
        StoreStaff storeStaff = new StoreStaff();
        storeStaff.setStoreId(storeId);
        storeStaff.setStaffId(staffId);

    }

    @Override
    public MerchantDto createMerchant(MerchantDto merchantDTO) throws BusinessException {
        if (merchantDTO==null){
            throw new BusinessException(CommonErrorCode.E_300009);
        }
        //手机号非空
        if (StringUtils.isEmpty(merchantDTO.getMobile())){
            throw new BusinessException(CommonErrorCode.E_100112);
        }
        //手机号格式匹配
        if (!PhoneUtil.isMatches(merchantDTO.getMobile())){
            throw new BusinessException(CommonErrorCode.E_100109);
        }
        //用户非空
        if (StringUtils.isEmpty(merchantDTO.getUsername())){
            throw new BusinessException(CommonErrorCode.E_100110);
        }

        if (StringUtils.isEmpty(merchantDTO.getPassword())){
            throw new BusinessException(CommonErrorCode.E_100111);
        }

        LambdaQueryWrapper<Merchant> merchant = new LambdaQueryWrapper<Merchant>()
                .eq(Merchant::getMobile, merchantDTO.getMobile());
        Integer num = merchantMapper.selectCount(merchant);
        if (num>0){
            throw new BusinessException(CommonErrorCode.E_100113);
        }
        CreateTenantRequestDTO createTenantRequestDTO = new CreateTenantRequestDTO();
        createTenantRequestDTO.setName(merchantDTO.getUsername());
        createTenantRequestDTO.setUsername(merchantDTO.getUsername());
        createTenantRequestDTO.setPassword(merchantDTO.getPassword());
        createTenantRequestDTO.setTenantTypeCode("huimin-merchant");
        createTenantRequestDTO.setBundleCode("huimin-merchant");
        createTenantRequestDTO.setMobile(merchantDTO.getMobile());
        TenantDTO tenantAndAccount = tenantService.createTenantAndAccount(createTenantRequestDTO);
        if (tenantAndAccount==null||tenantAndAccount.getId()==null){
            throw new BusinessException(CommonErrorCode.E_200012);
        }
        Long tenantId = tenantAndAccount.getId();
        LambdaQueryWrapper<Merchant> wrapper = new LambdaQueryWrapper<Merchant>();
          wrapper.eq(Merchant::getTenantId, tenantId);
        Integer numer = merchantMapper.selectCount(wrapper);
        if (numer>0) {
           throw new BusinessException(CommonErrorCode.E_200017);
        }
        Merchant entity = MerchantConvert.INSTANCE.dto2entity(merchantDTO);
        entity.setTenantId(tenantId);
        entity.setAuditStatus("0");
        merchantMapper.insert(entity);

        Store store = new Store();
        store.setStoreName("根门店");
        store.setMerchantId(entity.getId());
        store.setStoreStatus(true);
        StoreDTO storeDTO = StoreConvert.INSTANCE.entity2dto(store);
        System.out.println(storeDTO);
        StoreDTO storeDto = crestStore(storeDTO);

        StaffDTO staffDTO = new StaffDTO();
        staffDTO.setMobile(merchantDTO.getMobile());
        staffDTO.setUsername(entity.getUsername());
        staffDTO.setMerchantId(entity.getId());
        staffDTO.setStoreId(storeDto.getId());
        staffDTO.setStaffStatus(true);
        StaffDTO staffDTO1 = creatStaff(staffDTO);
        bindStaffToStore(store.getId(),staffDTO1.getId());

        MerchantDto merchantDto = MerchantConvert.INSTANCE.entity2dto(entity);
        return merchantDto;
    }

    @Override
    public MerchantDto queryMerchantByTenantId(Long tenantId) {
        LambdaQueryWrapper<Merchant> wrapper = new LambdaQueryWrapper<Merchant>().eq(Merchant::getTenantId, tenantId);
        Merchant merchant = merchantMapper.selectOne(wrapper);
        MerchantDto merchantDto = MerchantConvert.INSTANCE.entity2dto(merchant);

        return merchantDto;
    }

    @Override
    public PageVO<StoreDTO> queryStoreByPage(StoreDTO storeDTO, Integer pageNo, Integer pageSize) throws BusinessException{
        Page<Store> storePage = new Page<>(pageNo,pageSize);
        LambdaQueryWrapper<Store> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(!StringUtils.isEmpty(storeDTO.getMerchantId().toString()),
                Store::getMerchantId, storeDTO.getMerchantId());
        IPage<Store> storeIPage = storeMapper.selectPage(storePage, wrapper);
        List<StoreDTO> sDto = StoreConvert.INSTANCE.listentity2dto(storeIPage.getRecords());
        return new PageVO<>(sDto,storeIPage.getTotal(),pageNo,pageSize);

    }

    @Override
    public Boolean queryStoreInMerchant(Long storeId, Long merchantId) {
        LambdaQueryWrapper<Store> wrapper = new LambdaQueryWrapper<Store>().
                eq(Store::getId, storeId).eq(Store::getMerchantId, merchantId);
        Integer num = storeMapper.selectCount(wrapper);
        return num>0;
    }


}